require("View/DarkStreet/SubItem/DSActorItem")
---@type DarkStreetPlayerItem
local PlayerItem = require("View/DarkStreet/SubItem/DarkStreetPlayerItem")
local MineralItem = require("View/DarkStreet/SubItem/DarkStreetMineralItem")
local StoneItem = require("View/DarkStreet/SubItem/DarkStreetStoneItem")
local DSStoneDirItem = require("View/DarkStreet/SubItem/DSStoneDirItem")

---@class UIDarkStreetPlayerLayer : UIBase
UIDarkStreetPlayerLayer = UIBase.New(PanelResNames.UIDarkStreetPlayerLayer)
local t = UIDarkStreetPlayerLayer

function t.Init()
    UIBase.Init(t)
end

function t:OnCreate()
    self.isDirty = true
    ---@type DarkStreetPlayerItem[]
    self.playerItemList = {}
    ---@type DSStoneDirItem[]
    self.stoneDirItemList = {}
    local actorList = RedRob.ActorManager.GetActorList()
    for k,v in pairs(actorList) do
        self:CreatePlayerItem(v)
    end
    self:RegisterEvent(RedRob.Config.Event.ActorPosChanged,self.ActorPosChanged)
    self:RegisterEvent(RedRob.Config.Event.CameraPosChanged,self.CameraPosChanged)
    self:RegisterEvent(RedRob.Config.Event.PlayerInBattle,self.PlayerInBattle)
    self:RegisterEvent(RedRob.Config.Event.PlayerWin,self.PlayerWin)
    self:RegisterEvent(RedRob.Config.Event.PlayerStartReborn,self.PlayerStartReborn)
    self:RegisterEvent(RedRob.Config.Event.ActorDead,self.ActorDead)
    self:RegisterEvent(RedRob.Config.Event.PlayerReborn,self.PlayerReborn)
    self:RegisterEvent(RedRob.Config.Event.ActorCreate,self.ActorCreate)
    self:RegisterEvent(RedRob.Config.Event.ActorDestroy,self.ActorDestroy)
    self:RegisterEvent(RedRob.Config.Event.PlayerEmojiShow,self.EmojiShow)
    self:RegisterEvent(RedRob.Config.Event.PlayerAttrReduce,self.PlayerAttrReduce)
    self:RegisterEvent(RedRob.Config.Event.PlayerHpChanged,self.PlayerHpChanged)
    self:RegisterEvent(RedRob.Config.Event.PlayerResourceUpdate,self.PlayerResourceUpdate)
    self:RegisterEvent(RedRob.Config.Event.PlayerResourceChange,self.PlayerResourceChange)
    self:RegisterEvent(RedRob.Config.Event.BattleTimeInit,self.BattleTimeInit)
    self:RegisterEvent(RedRob.Config.Event.BuffChanged,self.BuffChanged)

    RedRob.ClientBattle.RegisterLateUpdateCallback(self.LateUpdateCallback,self)
end

function t:OnEnable()

end
function t:OnDisable()

end

function t:OnDestroy()
    for k,v in pairs(self.playerItemList) do
        v:OnDestroy()
    end
    for k,v in pairs(self.stoneDirItemList) do
        v:OnDestroy()
    end
    self.playerItemList = nil
    self.stoneDirItemList = nil
end
---@param player RedRob.Player
function t:CreatePlayerItem(player)
    local item = self.playerItemList[player:GetId()]
    if item then return end
    local obj = newGComponent("Btn_HeroPos","UIDarkStreet")
    item = PlayerItem.New(player:GetId(),RedRob.Config.ActorType.player,self)
    item:OnCreate(obj)
    item:Refresh(player)
    self.playerItemList[player:GetId()] = item
    self.fguiObj:AddChild(obj)
    self:ActorPosChanged()
    self:BuffChanged(player)
    self:UpdatePos(item,player,true)
end
function t:GetItem(id)
    return self.playerItemList[id]
end
function t:IsMe(player)
    return RedRob.KeyController.GetCtrl() == player
end
--region 消息处理
function t:CameraPosChanged()
    self.isDirty = true
end

function t:ActorPosChanged()
    self.isDirty = true
end
--已复活
---@param player RedRob.Player
function t:PlayerReborn(player)
    local item = self:GetItem(player:GetId())
    if not item then return end
    item:SetVisible(true)
    self:UpdatePos(item,player,true)
    self:ActorPosChanged(player)
    if player == RedRob.KeyController.GetCtrl() then
        closeUI(PanelNames.UIDarkStreetDead)
    end
end
--开始计时复活
---@param player RedRob.Player
function t:PlayerStartReborn(player,time)
    if self:IsMe(player) and not logicMgr.DarkStreetMgr.isInResult then
        showUI(PanelNames.UIDarkStreetDead,time)
    end
end
---@param player RedRob.Player
function t:PlayerWin(player)
    local item = self:GetItem(player:GetId())
    if not item then return end
    item:SetInBattle(false)
    local data = RedRob.GameMode.GetPlayerData(player:GetId())
    if data then
        item:ShowReward(true,data.resNum)
        item:ShowChangeReward(data.resNumChange)
        item:ShowWinPunishBuff(data.buff)
    else
        --logError("找不到战斗数据："..player:GetId())
    end
end

---@param player RedRob.Player
---@param attackPlayer RedRob.Player
function t:ActorDead(player, attackPlayer)
    local item = self:GetItem(player:GetId())
    if not item then return end
    if item.actorType == RedRob.Config.ActorType.player then
        item:SetInBattle(false)
    end
    local data = RedRob.GameMode.GetPlayerData(player:GetId())
    if data then
        item:ShowReward(true,data.resNum)
        item:ShowChangeReward(data.resNumChange)
        item:ShowWinPunishBuff(data.buff)
        logicMgr.DarkStreetMgr.AddBroadcastMsg(attackPlayer,player,data.resNumChange)
    else
        --logError("找不到战斗数据："..player:GetId())
    end
end

---@param player RedRob.Player
function t:PlayerInBattle(player)
    if player:GetTarget() and player:GetTarget().actorType ~= RedRob.Config.ActorType.player then
        return
    end
    local item = self:GetItem(player:GetId())
    if not item then return end
    item:SetInBattle(player:IsInBattle())
    if player:IsInBattle() then
        if self:IsMe(player) or self:IsMe(player:GetTarget()) then --自己战斗才显示血
            item:SetHp(1,1)
            item:HpBarVisible(true)
        else
            item:HpBarVisible(false)
        end
    end
    if player:IsDead() then
        item:ShowWinPunishBuff(0)
        item:SetVisible(false)
    end
end
---@param actor RedRob.Pawn
function t:IsPlayer(actor)
    if not actor then return false end
    return actor.actorType == RedRob.Config.ActorType.player
end
---@param actor RedRob.Pawn
function t:ActorCreate(actor)
    local ActorType = RedRob.Config.ActorType
    if actor.actorType == ActorType.player then
        self:CreatePlayerItem(actor)
    elseif actor.actorType == ActorType.minerals then
        self:CreateMineralItem(actor)
    elseif actor.actorType == ActorType.stone then
        self:CreateStoneItem(actor)
    end
end
---@param actor RedRob.Player
---@param attackActor RedRob.Player
function t:PlayerHpChanged(actor,attackActor)
    local item = self:GetItem(actor:GetId())
    if not item then return end
    item:SetHp(actor:GetHp(),actor:GetHpMax())
end

---@param player RedRob.Player
function t:UpdatePos(item,player)
    if not item or not player then return end
    local p = player:GetPos()
    self:UpdatePos2(item,p.x,p.y)
end
function t:UpdatePos2(item,px,py)
    if not item then return end
    local x,y,z = RedRob.ClientBattle.LocalToWorld(px,py,0)
    x,y = RedRob.ClientBattle.WorldToScreenPoint(x,y,z)
    x,y = FGUIScreenToLocal(self.fguiObj,x,y)
    item:SetPos(x,y)
end
---@param item DSStoneDirItem
function t:UpdateStoneDir(item,actor)
    if not item or not actor then return end
    local p = actor:GetPos()
    local x,y,z = RedRob.ClientBattle.LocalToWorld(p.x,p.y,p.z)
    x,y = RedRob.ClientBattle.WorldToScreenPoint(x,y,z)
    x,y = FGUIScreenToLocal(self.fguiObj,x,y)
    --
    p = RedRob.KeyController:GetCtrl():GetPos()
    local x1,y1,z1 = RedRob.ClientBattle.LocalToWorld(p.x,p.y,p.z)
    x1,y1 = RedRob.ClientBattle.WorldToScreenPoint(x,y,z)
    x1,y1 = FGUIScreenToLocal(self.fguiObj,x,y)
    item:SetPos(x,y,x1,y1)
end
function t:LateUpdateCallback(dt)
    if not self.isDirty then return end
    self.isDirty = false
    for k,v in pairs(self.playerItemList) do
        local actor = RedRob.ActorManager.GetActor(k)
        if v.actorType == RedRob.Config.ActorType.minerals then
            if not actor or actor:IsDead() then
                v:SetVisible(false)
            end
        end
        if v:IsFollowPos() then
            self:UpdatePos2(v,v.followX,v.followY)
        else
            self:UpdatePos(v,actor)
        end
    end
    for k,v in pairs(self.stoneDirItemList) do
        self:UpdatePos(v,RedRob.ActorManager.GetActor(v.id))
    end
    local temp = RedRob.ActorManager.GetSortActorList()
    for i = #temp,1,-1 do
        local actor = temp[i]
        local item = self.playerItemList[actor:GetId()]
        if item then
            if not actor:IsDead() and RedRob.CameraController.IsPlayerInScreen(actor) then
                self.fguiObj:SetChildIndex(item.fguiObj,0)
            end
        end
    end
end
function t:EmojiShow(playerId,emojiName)
    local item = self:GetItem(playerId)
    if not item then return end
    item:ShowEmoji(emojiName)
end
function t:PlayerAttrReduce(playerId,attrReduce)
    --[[local item = self:GetItem(playerId)
    if not item then return end
    local data = logicMgr.DarkStreetMgr.GetPlayerData(playerId)
    if data then
        item:ShowBuff(data.buff)
    end]]

end
function t:PlayerResourceUpdate(playerId,curNum)
    local item = self:GetItem(playerId)
    if not item then return end
    item:SetRewardCount(curNum)
end
function t:PlayerResourceChange(playerId,changeNum)
end
function t:BattleTimeInit()
    local bat = RedRob.ClientBattle
    if bat.IsBattleWaiting() then
        for k,v in pairs(self.playerItemList) do
            if v.actorType == RedRob.Config.ActorType.player then
                v:ShowReward(false)
            end
        end
    else
        for k,v in pairs(self.playerItemList) do
            local data = RedRob.GameMode.GetPlayerData(k)
            if data and v.actorType == RedRob.Config.ActorType.player then
                v:ShowReward(true,data.resNum)
            end
        end
    end
end
---@param actor RedRob.Pawn
function t:BuffChanged(actor)
    local item = self:GetItem(actor:GetId())
    if not item then return end
    item:ShowHeadBuff(actor:GetBuffList())
end
---@param actor RedRob.Minerals
function t:CreateMineralItem(actor)
    if not actor:IsBuff() then
        return
    end
    local obj = newGComponent("Btn_BoxPos","UIDarkStreet")
    local item = MineralItem.New(actor:GetId(),RedRob.Config.ActorType.minerals,self)
    item:OnCreate(obj)
    item:Refresh(actor)
    self.fguiObj:AddChild(obj)
    self.playerItemList[actor:GetId()] = item
    self:ActorPosChanged()
    self:UpdatePos(item,actor,true)
end
---@param actor RedRob.Stone
function t:CreateStoneItem(actor)
    local obj = newGComponent("Btn_Stone","UIDarkStreet")
    local item = StoneItem.New(actor:GetId(),RedRob.Config.ActorType.stone,self)
    item:OnCreate(obj)
    item:Refresh(actor)
    self.fguiObj:AddChild(obj)
    self.playerItemList[actor:GetId()] = item
    self:ActorPosChanged()
    self:UpdatePos(item,actor,true)
    --
    local obj1 = newGComponent("Com_StonePos","UIDarkStreet")
    local item1 = DSStoneDirItem.New()
    item1:OnCreate(obj1)
    item1:Refresh(actor)
    self.fguiObj:AddChild(obj1)
    self.stoneDirItemList[actor:GetId()] = item1
    self:UpdatePos(item1,actor)
end
---@param item DSActorItem
function t:DestroyActorItem(item)
    if not item then return end
    item:OnDestroy()
    self.playerItemList[item.actorId] = nil
end

---@param actor RedRob.Pawn
function t:ActorDestroy(actor)
    local id = actor:GetId()
    local item = self.playerItemList[id]
    if item and item:CanDestroy() then
        self:DestroyActorItem(item)
    end
    item = self.stoneDirItemList[id]
    if item then
        item:OnDestroy()
        self.stoneDirItemList[id] = nil
    end
end
--endregion 消息处理
return t